package org.mspring.mlog.service;

import java.util.List;

import org.apache.commons.lang3.ClassUtils;
import org.mspring.mlog.dao.JobDao;
import org.mspring.mlog.entity.Job;
import org.mspring.mlog.scheduler.SchedulerService;
import org.mspring.platform.dao.Page;
import org.mspring.platform.dao.query.QueryBuilder;
import org.mspring.platform.utils.StringUtils;
import org.mspring.platform.utils.exception.BusinessException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 *
 * @author Gao Youbo
 * @since 2013-06-18 16:34:42
 */
@Service
@Transactional
public class JobService {

    private static final Logger log = LoggerFactory.getLogger(JobService.class);

    @Autowired
    private JobDao jobDao;
    @Autowired
    private SchedulerService schedulerService;

    public Job get(long id) {
        return jobDao.get(id);
    }

    public Page<Job> listPage(QueryBuilder queryBuilder, Page<Job> page) {
        return jobDao.listPage(queryBuilder, page);
    }

    /**
     * @param enabled
     * @param ids
     */

    public void setEnabled(boolean enabled, Long... ids) {
        if (ids == null || ids.length == 0) {
            return;
        }
        for (Long id : ids) {
            jobDao.setEnabled(id, true);
        }
    }

    /**
     * @param ids
     * @param expressions
     */

    public void setExpression(Long[] ids, String[] expressions) {
        if (ids == null || ids.length == 0) {
            return;
        }
        for (int i = 0; i < ids.length; i++) {
            long id = ids[i];
            String expression = expressions[i];
            jobDao.setExpression(id, expression);
        }
    }

    /**
     * @param ids
     * @param execTypes
     */

    public void setExecTypes(Long[] ids, String[] execTypes) {
        if (ids == null || ids.length == 0) {
            return;
        }
        for (int i = 0; i < ids.length; i++) {
            long id = ids[i];
            String execType = execTypes[i];
            jobDao.setExecType(id, execType);
        }
    }

    /**
     * @param id
     */
    public void reloadJobServer(long id) {
        Job job = get(id);
        reloadJobServer(job);
    }

    /**
     * @param job
     */
    public void reloadJobServer(Job job) {
        String className = job.getJobClass();
        if (StringUtils.isBlank(className)) {
            log.error("can't register job server, jobClass is null.");
            throw new BusinessException("can't register job server, jobClass is null.");
        }
        Class<?> clazz = null;
        try {
            clazz = ClassUtils.getClass(className);
        } catch (ClassNotFoundException e) {
            log.error(String.format("can't register job server, class not found. [id=%s, className=%s]", job.getId(), className));
            throw new BusinessException(String.format("can't register job server, class not found. [id=%s, className=%s]", job.getId(), className));
        }

        String execType = job.getExecType();
        if (StringUtils.isBlank(execType)) {
            execType = Job.ExecType.SIMPLE;
        }
        try {
            if (execType.equalsIgnoreCase(Job.ExecType.CRON)) {
                schedulerService.schedule(job.getId().toString(), clazz, job.getExpression());
            } else {
                Long repeatInterval = new Long(job.getExpression());
                schedulerService.schedule(job.getId().toString(), clazz, repeatInterval);
            }
        } catch (Exception e) {
            log.error(String.format("can't register job server. [id=%s, className=%s, execType=%s, expression=%s]", job.getId(), className, execType, job.getExpression()));
            throw new BusinessException(String.format("can't register job server. [id=%s, className=%s, execType=%s, expression=%s]", job.getId(), className, execType, job.getExpression()));
        }
    }

    public void loadJobServer() {
        log.info("init JobService...");
        List<Job> enabledJobs = jobDao.listEnabled();
        for (Job job : enabledJobs) {
            try {
                reloadJobServer(job);
                log.info(String.format("Job Server load success. name = [id=%s, className=%s, execType=%s, expression=%s]", job.getId(), job.getClass(), job.getExecType(), job.getExpression()));
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
        }
    }
}
